home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 47 / Amiga Format AFCD47 (Issue 131, Xmas 1999).iso / -in_the_mag- / workbench / scanners / abaton / scan / scan.c < prev    next >
C/C++ Source or Header  |  1999-10-11  |  25KB  |  682 lines

  1. /********************************************************************************* 
  2.  * Abaton SCAN 300/FB (Ricoh IS30-M2) flatbed scanner controller                 *
  3.  *-------------------------------------------------------------------------------*
  4.  * FILE:   scan.c                                                                *
  5.  * AUTHOR: Chris Sterne                                                          *
  6.  * DATE:   March 3, 1999                                                         *
  7.  *********************************************************************************/
  8.  
  9. #include <exec/types.h>
  10. #include <exec/memory.h>
  11. #include <libraries/dos.h>
  12. #include <libraries/iffparse.h>
  13. #include <resources/misc.h>
  14. #include <devices/parallel.h>
  15. #include <hardware/cia.h>
  16. #include <clib/dos_protos.h>
  17. #include <clib/exec_protos.h>
  18. #include <clib/alib_protos.h>
  19. #include <clib/misc_protos.h>
  20. #include <clib/exec_protos.h>
  21. #include <clib/iffparse_protos.h>
  22. #include <stdio.h>
  23. #include <ctype.h>
  24. #include <string.h>
  25. #include <stdlib.h>
  26.  
  27. #include "packer.h"
  28.  
  29. void __regargs __chkabort(void);
  30.  
  31. void __regargs __chkabort(void)         /* Disable SAS/C Control-C checking. */
  32. {
  33. }
  34.  
  35. void __regargs __main(char *);          /* Replaces the SAS/C __main version. */
  36.  
  37. void __main(char *CommandLine)
  38. {
  39.   exit (main(CommandLine));
  40. }
  41.  
  42. #define cmpNone     0                   /* BMHD chunk declarations. */
  43. #define cmpByteRun1 1
  44. #define mskNone     0
  45.  
  46. typedef UBYTE Masking;
  47. typedef UBYTE Compression;
  48.  
  49. struct BitMapHeader                     /* BMHD chunk structure. */
  50. {
  51.   UWORD w, h;
  52.   UWORD x, y;
  53.   UBYTE nPlanes;
  54.   Masking masking;
  55.   Compression compression;
  56.   UBYTE pad1;
  57.   UWORD transparentColor;
  58.   UBYTE xAspect, yAspect;
  59.   WORD pageWidth, pageHeight;
  60. };
  61.  
  62. __far extern struct CIA ciaa, ciab;
  63.  
  64. struct Library *IFFParseBase;
  65. APTR MiscBase;
  66.  
  67. void DisplayHelp(void);
  68. void WriteImageFile(char *, BOOL);
  69. BOOL SendCommand(struct IOExtPar *, char *, char *);
  70. BOOL ReceiveData(UBYTE *, ULONG);
  71.  
  72. char *VersionString   = "$VER:Scan 1.0 (3.3.1999)";
  73. char *CommandTemplate = "SCAN,TO,QUIET/S,AREA/K,DENSITY/N/K,SENSITIVITY/N/K,INVERT/S,REFLECT/S,COMMAND/K";
  74.  
  75. /*-------------------------------------------------------------------------------*
  76.  * FUNCTION: main                                                                *
  77.  *-------------------------------------------------------------------------------*
  78.  * This is the main entry point for the program.                                 *
  79.  *-------------------------------------------------------------------------------*
  80.  * INPUTS: CommandLine = CLI command line.                                       *
  81.  *                                                                               *
  82.  * OUTPUT: Always EXIT_SUCCESS.                                                  *
  83.  *-------------------------------------------------------------------------------*/
  84.  
  85. int main(char *CommandLine)
  86. {
  87.   struct RDArgs *RDArguments;
  88.   LONG Arguments[9];
  89.   char Buffer[6];
  90.   struct MsgPort *ParallelMP;
  91.   struct IOExtPar *ParallelIO;
  92.   BOOL Help, Quiet;
  93.   
  94.   if ((RDArguments = (struct RDArgs *)AllocDosObject(DOS_RDARGS, NULL)) != NULL)
  95.   {
  96.     RDArguments->RDA_Source.CS_Buffer = CommandLine;
  97.     RDArguments->RDA_Source.CS_Length = strlen(CommandLine) + 1;
  98.     RDArguments->RDA_Source.CS_CurChr = 0;
  99.     RDArguments->RDA_DAList           = NULL;
  100.     RDArguments->RDA_Buffer           = NULL;
  101.     RDArguments->RDA_Flags            = RDAF_NOPROMPT;
  102.  
  103.     *(CommandLine + RDArguments->RDA_Source.CS_Length - 1) = '\n';
  104.  
  105.     Arguments[0] = NULL;
  106.     Arguments[1] = NULL;
  107.     Arguments[2] = NULL;
  108.     Arguments[3] = NULL;
  109.     Arguments[4] = NULL;
  110.     Arguments[5] = NULL;
  111.     Arguments[6] = NULL;
  112.     Arguments[7] = NULL;
  113.     Arguments[8] = NULL;
  114.  
  115.     if (ReadArgs(CommandTemplate, Arguments, RDArguments) != NULL)    
  116.     {
  117.       if ((ParallelMP = CreatePort (0,0)) != NULL)
  118.       {
  119.         if ((ParallelIO = (struct IOExtPar *)CreateExtIO(ParallelMP, sizeof(struct IOExtPar))) != NULL)
  120.         {
  121.           Quiet = FALSE;
  122.           Help  = TRUE;
  123.           
  124.           if ((BOOL)Arguments[8])
  125.           {
  126.             /*----------------------*
  127.              * Raw scanner command. *
  128.              *----------------------*/
  129.             
  130.             SendCommand(ParallelIO, (char *)Arguments[8], NULL);
  131.             Help = FALSE;
  132.           }
  133.           
  134.           if ((BOOL)Arguments[7])
  135.           {
  136.             /*--------------------------*
  137.              * Enable image reflection. *
  138.              *--------------------------*/
  139.             
  140.             SendCommand(ParallelIO, "RF", "S");
  141.             Help = FALSE;
  142.           }
  143.   
  144.           if ((BOOL)Arguments[6])
  145.           {
  146.             /*-------------------------*
  147.              * Enable image inversion. *
  148.              *-------------------------*/
  149.             
  150.             SendCommand(ParallelIO, "IV", "S");
  151.             Help = FALSE;
  152.           }
  153.                 
  154.           if (Arguments[5] != NULL)
  155.           {
  156.             /*----------------------------*
  157.              * Set the sensitivity level. *
  158.              *----------------------------*/
  159.             
  160.             stci_h(Buffer, *((int *)Arguments[5]));
  161.             SendCommand(ParallelIO, "LV", Buffer);
  162.             Help = FALSE;
  163.           }
  164.                
  165.           if (Arguments[4] != NULL)
  166.           {
  167.             /*-----------------------------*
  168.              * Set the scan pixel density. *
  169.              *-----------------------------*/
  170.             
  171.             stci_d(Buffer, *((int *)Arguments[4]));
  172.             SendCommand(ParallelIO, "DN", Buffer);
  173.             Help = FALSE;
  174.           }
  175.   
  176.           if (Arguments[3] != NULL)
  177.           {
  178.             /*--------------------*
  179.              * Set the scan area. *
  180.              *--------------------*/
  181.             
  182.             SendCommand(ParallelIO, "DA", (char *)Arguments[3]);
  183.             Help = FALSE;
  184.           }
  185.           
  186.           if ((BOOL)Arguments[2])
  187.           {
  188.             /*--------------------*
  189.              * Select quiet mode. *
  190.              *--------------------*/
  191.             
  192.             Quiet = TRUE;
  193.             Help  = FALSE;
  194.           }
  195.           
  196.           if (Arguments[1] != NULL)
  197.           {
  198.             if (stricmp((char *)Arguments[1], "?") != 0)
  199.             {
  200.               /*--------------------------------------------------*
  201.                * An image file name was given.  Scan the selected *
  202.                * area, and save the data to the file.             *
  203.                *--------------------------------------------------*/
  204.               
  205.               SendCommand(ParallelIO, "RA", NULL);
  206.               WriteImageFile((char *)Arguments[1], Quiet);
  207.               
  208.               /*--------------------------------------------*
  209.                * Turn off the illumination lamp, and return *
  210.                * the image properties to normal.            *
  211.                *--------------------------------------------*/
  212.               
  213.               SendCommand(ParallelIO, "FL", "L");
  214.               SendCommand(ParallelIO, "IV", "R");
  215.               SendCommand(ParallelIO, "RF", "R");
  216.               Help = FALSE;
  217.             }
  218.           }
  219.           
  220.           if (Help)
  221.             DisplayHelp();
  222.           
  223.           DeleteExtIO((struct IORequest*)ParallelIO);
  224.         }
  225.         else
  226.           printf("Unable to create IORequest.\n");
  227.  
  228.         DeletePort(ParallelMP);
  229.       }
  230.       else
  231.         printf("Unable to create message port.\n");
  232.       
  233.       FreeArgs(RDArguments); 
  234.     }
  235.     
  236.     FreeDosObject(DOS_RDARGS, RDArguments);
  237.   }
  238.         
  239.   return EXIT_SUCCESS;
  240. }
  241.  
  242. /*-------------------------------------------------------------------------------*
  243.  * FUNCTION: DisplayHelp                                                         *
  244.  *-------------------------------------------------------------------------------*
  245.  * This function displays command arguments and purpose.                         *
  246.  *-------------------------------------------------------------------------------*
  247.  * INPUTS: None.                                                                 *
  248.  *                                                                               *
  249.  * OUTPUT: None.                                                                 *
  250.  *-------------------------------------------------------------------------------*/
  251.  
  252. void DisplayHelp(void)
  253. {
  254.   printf("-------------------------------------------------------\n");
  255.   printf(" Abaton SCAN300/FB (Ricoh IS30-M2) scanner controller\n");
  256.   printf("    for use with a custom Parallel Port interface.\n");
  257.   printf("-------------------------------------------------------\n");
  258.   printf("   By Chris Sterne                       Version 1.0\n");
  259.   printf("-------------------------------------------------------\n\n");
  260.           
  261.   printf("%s\n\n", CommandTemplate);
  262.           
  263.   printf("TO is an ILBM image file to create.\n\n");
  264.  
  265.   printf("QUIET prevents the display of information when scanning.\n\n");
  266.  
  267.   printf("DENSITY selects the scan Dots Per Inch (DPI):\n");
  268.   printf("  300, 240, 200, or 180\n\n");
  269.           
  270.   printf("AREA selects the scan area:\n");
  271.   printf("  A4             (210mm x 297mm)\n");
  272.   printf("  A5             (210mm x 150mm)\n");
  273.   printf("  B5             (176mm x 250mm)\n");
  274.   printf("  B6             (176mm x 125mm)\n");
  275.   printf("  LT             (8.5\" x 11.0\" Letter)\n");
  276.   printf("  14             (8.5\" x 14.0\" Legal)\n");
  277.   printf("  AT             (8.1\" x 14.0\")\n");
  278.   printf("  CD             (3.5\" x 2.0\" Business Card)\n");
  279.   printf("  (BX+BW,PY+PH)  Byte X offset and width, pixel Y offset and height.\n");
  280.   printf("                 (A byte represents eight horizontal pixels)\n\n");
  281.  
  282.   printf("SENSITIVITY adjusts the response to image variations.\n");
  283.   printf("Range is 0 to 15, with 0 being the lowest sensitivity.\n\n");
  284.  
  285.   printf("INVERT produces an inverted image.\n\n");
  286.  
  287.   printf("REFLECT produces an image reflected about the Y-axis.\n\n");
  288.  
  289.   printf("COMMAND allows sending a raw command to the scanner.\n");
  290.   printf("An \'<ESC>!\' prefix and \'<CR>\' suffix will be added.\n\n");
  291.  
  292.   return;
  293. }
  294.  
  295. /*-------------------------------------------------------------------------------*
  296.  * FUNCTION: SendCommand                                                         *
  297.  *-------------------------------------------------------------------------------*
  298.  * This function builds a command code sequence, then sends it to the scanner.   *
  299.  * (eg. <ESC> ! <Command> <Argument> <CR>)                                       *
  300.  *-------------------------------------------------------------------------------*
  301.  * INPUTS: ParallelIO = Parallel device I/O request.                             *
  302.  *         Command    = Scanner command string.                                  *
  303.  *         Argument   = Scanner command argument string.                         *
  304.  *                                                                               *
  305.  * OUTPUT: TRUE if successful, or FALSE if aborted by pressing Control-C.        *
  306.  *-------------------------------------------------------------------------------*/
  307.  
  308. BOOL SendCommand(struct IOExtPar *ParallelIO, char *Command, char *Argument)
  309. {
  310.   ULONG WaitSignals, ReturnSignals;
  311.   char *Parts[4];
  312.   UBYTE Index;
  313.   BOOL Success;
  314.  
  315.   if (OpenDevice(PARALLELNAME, 0, (struct IORequest *)ParallelIO, 0) == 0)
  316.   {
  317.     ParallelIO->IOPar.io_Command = CMD_WRITE;
  318.     ParallelIO->IOPar.io_Flags   = 0;
  319.  
  320.     /*--------------------------------------------*
  321.      * The scanner expects upper-case ASCII text. *
  322.      *--------------------------------------------*/
  323.  
  324.     if (Command != NULL)
  325.       strupr(Command);
  326.     
  327.     if (Argument != NULL)
  328.       strupr(Argument);
  329.     
  330.     /*-----------------------------*
  331.      * Build the command sequence. *
  332.      *-----------------------------*/
  333.     
  334.     Parts[0] = "\x1B!";
  335.     Parts[1] = Command;
  336.     Parts[2] = Argument;
  337.     Parts[3] = "\x0D";
  338.  
  339.     WaitSignals = 1 << ((struct IORequest *)ParallelIO)->io_Message.mn_ReplyPort->mp_SigBit | SIGBREAKF_CTRL_C;
  340.     Success     = TRUE;
  341.     Index       = 0;
  342.  
  343.     /*-----------------------------------------*
  344.      * Send each part of the command sequence. *
  345.      *-----------------------------------------*/
  346.  
  347.     do
  348.     {
  349.       if (Parts[Index] != NULL)
  350.       {
  351.         ParallelIO->IOPar.io_Data    = Parts[Index];
  352.         ParallelIO->IOPar.io_Length  = strlen(ParallelIO->IOPar.io_Data);
  353.   
  354.         SendIO((struct IORequest *)ParallelIO);
  355.         ReturnSignals = Wait(WaitSignals);
  356.   
  357.         if (ReturnSignals == SIGBREAKF_CTRL_C)
  358.         {
  359.           AbortIO((struct IORequest *)ParallelIO);
  360.           WaitIO((struct IORequest *)ParallelIO);
  361.           Success = FALSE;
  362.         }
  363.       }
  364.  
  365.       Index ++;
  366.     }
  367.     while ((Success) && (Index != 4));
  368.   
  369.     CloseDevice((struct IORequest *)ParallelIO);
  370.   }
  371.   else
  372.   {
  373.     printf("Unable to open the Parallel Device.\n");
  374.     Success = FALSE;
  375.   }
  376.  
  377.   return Success;
  378. }
  379.  
  380. /*-------------------------------------------------------------------------------*
  381.  * FUNCTION: WriteImageFile                                                      *
  382.  *-------------------------------------------------------------------------------*
  383.  * This function reads scan data, and writes it as an IFF compressed ILBM image  *
  384.  * file.                                                                         *
  385.  *-------------------------------------------------------------------------------*
  386.  * INPUTS: FileName = Parallel device I/O request.                               *
  387.  *         Quiet    = If TRUE, don't print scan information.                     *
  388.  *                                                                               *
  389.  * OUTPUT: None.                                                                 *
  390.  *-------------------------------------------------------------------------------*/
  391.  
  392. void WriteImageFile(char *FileName, BOOL Quiet)
  393. {
  394.   struct IFFHandle *IFFHandle;
  395.   struct BitMapHeader *BitMapHeader;
  396.   ULONG ID_ILBM, ID_BMHD, ID_BODY;
  397.   char Buffer[6];
  398.   BYTE *ReadBuffer, *WriteBuffer;
  399.   int Density, ByteWidth, RowWidth, PixelHeight;
  400.   ULONG TotalSize, CompressSize;
  401.   BOOL Success;
  402.  
  403.   if ((IFFParseBase = OpenLibrary("iffparse.library", 37)) != NULL)
  404.   {
  405.     if ((MiscBase = OpenResource(MISCNAME)) != NULL)
  406.     {
  407.       /*------------------------------------------------*
  408.        * Acquire access to the Parallel Port resources. *
  409.        *------------------------------------------------*/
  410.       
  411.       if (AllocMiscResource(MR_PARALLELPORT, "Scan") == NULL)
  412.       {
  413.         if (AllocMiscResource(MR_PARALLELBITS, "Scan") == NULL)
  414.         {
  415.           /*------------------------------------------*
  416.            * Drive the interface READ# signal active. *
  417.            *------------------------------------------*/
  418.  
  419.           ciab.ciapra  &= ~0x04;
  420.           ciab.ciaddra |= 0x04;
  421.         
  422.           /*-------------------------------------------*
  423.            * Read the scan information section header. *
  424.            *-------------------------------------------*/
  425.         
  426.           Success = FALSE;
  427.         
  428.           if (ReceiveData(Buffer, 3))
  429.           {
  430.             /*-------------------------------*
  431.              * Read the scan density digits. *
  432.              *-------------------------------*/
  433.           
  434.             if (ReceiveData(Buffer, 3))
  435.             {
  436.               Buffer[3] = NULL;
  437.               stcd_i(Buffer, &Density);
  438.             
  439.               /*-------------------------------------*
  440.                * Read the scan bytes per row digits. *
  441.                *-------------------------------------*/
  442.           
  443.               if (ReceiveData(Buffer, 4))
  444.               {
  445.                 Buffer[4] = NULL;
  446.                 stcd_i(Buffer, &ByteWidth);
  447.               
  448.                 /*----------------------------------*
  449.                  * Read the total scan rows digits. *
  450.                  *----------------------------------*/
  451.           
  452.                 if (ReceiveData(Buffer, 5))
  453.                 {
  454.                   Buffer[5] = NULL;
  455.                   stcd_i(Buffer, &PixelHeight);
  456.               
  457.                   /*------------------------------------*
  458.                    * Read the scan data section header. *
  459.                    *------------------------------------*/
  460.           
  461.                   if (ReceiveData(Buffer, 3))
  462.                   {
  463.                     /*--------------------------------------------*
  464.                      * If requested, print some scan information. *
  465.                      *--------------------------------------------*/
  466.                    
  467.                     if (!Quiet)
  468.                     {
  469.                       printf("Pixels per inch: %d\n", Density);
  470.                       printf("Pixel width:     %d\n", ByteWidth * 8);
  471.                       printf("Pixel height:    %d\n", PixelHeight);
  472.                     }
  473.                         
  474.                     if ((IFFHandle = AllocIFF()) != NULL)
  475.                     {
  476.                       InitIFFasDOS(IFFHandle);
  477.                 
  478.                       if ((IFFHandle->iff_Stream = Open(FileName, MODE_NEWFILE)) != NULL)
  479.                       {
  480.                         OpenIFF(IFFHandle, IFFF_WRITE);
  481.  
  482.                         ID_ILBM = MAKE_ID('I', 'L', 'B', 'M');
  483.                         ID_BMHD = MAKE_ID('B', 'M', 'H', 'D');
  484.                         ID_BODY = MAKE_ID('B', 'O', 'D', 'Y');
  485.                           
  486.                         /*--------------------*
  487.                          * Begin an IFF form. *
  488.                          *--------------------*/
  489.         
  490.                         PushChunk(IFFHandle, ID_ILBM, ID_FORM, IFFSIZE_UNKNOWN);
  491.                 
  492.                         if ((BitMapHeader = AllocVec(sizeof(struct BitMapHeader), MEMF_ANY)) != NULL)
  493.                         {
  494.                           BitMapHeader->w                = ByteWidth * 8;
  495.                           BitMapHeader->h                = PixelHeight;
  496.                           BitMapHeader->x                = 0;
  497.                           BitMapHeader->y                = 0;
  498.                           BitMapHeader->nPlanes          = 1;
  499.                           BitMapHeader->masking          = mskNone;
  500.                           BitMapHeader->compression      = cmpByteRun1;
  501.                           BitMapHeader->transparentColor = 1;
  502.                           BitMapHeader->xAspect          = 1;
  503.                           BitMapHeader->yAspect          = 1;
  504.                           BitMapHeader->pageWidth        = BitMapHeader->w;
  505.                           BitMapHeader->pageHeight       = BitMapHeader->h;
  506.           
  507.                           /*-----------------------*
  508.                            * Add an BitMap header. *
  509.                            *-----------------------*/
  510.                             
  511.                           PushChunk(IFFHandle, ID_ILBM, ID_BMHD, sizeof(struct BitMapHeader));
  512.                           WriteChunkBytes(IFFHandle, BitMapHeader, sizeof(struct BitMapHeader));
  513.                           PopChunk(IFFHandle);
  514.                           
  515.                           /*-----------------*
  516.                            * Add image data. *
  517.                            *-----------------*/
  518.                                 
  519.                           PushChunk(IFFHandle, ID_ILBM, ID_BODY, IFFSIZE_UNKNOWN);
  520.                           
  521.                           TotalSize = ByteWidth * PixelHeight;
  522.                           
  523.                           /*------------------------------------------------------*
  524.                            * Ensure an even number of bytes per raster scan-line. *
  525.                            *------------------------------------------------------*/
  526.                           
  527.                           if (ByteWidth & 0x01)
  528.                             RowWidth = ByteWidth + 1;
  529.                           else
  530.                             RowWidth = ByteWidth;
  531.                           
  532.                           ReadBuffer  = AllocVec(RowWidth, MEMF_ANY);
  533.                           WriteBuffer = AllocVec(MaxPackedSize(RowWidth), MEMF_ANY);
  534.                           
  535.                           if ((ReadBuffer != NULL) && (WriteBuffer != NULL))
  536.                           {
  537.                             do
  538.                             {
  539.                               if (ReceiveData(ReadBuffer, ByteWidth))
  540.                               {
  541.                                 CompressSize = PackRow(ReadBuffer, WriteBuffer, RowWidth);
  542.                                 WriteChunkBytes(IFFHandle, WriteBuffer, CompressSize);
  543.                                 TotalSize -= ByteWidth;
  544.                               }
  545.                               else
  546.                                 TotalSize = 0;
  547.                             }
  548.                             while (TotalSize != 0);
  549.                           }
  550.                           
  551.                           PopChunk(IFFHandle);
  552.                           FreeVec(ReadBuffer);
  553.                           FreeVec(WriteBuffer);
  554.                           
  555.                           /*-------------------------------------*
  556.                            * Read the scan termination sequence. *
  557.                            *-------------------------------------*/
  558.           
  559.                           if (Success = ReceiveData(Buffer, 4))
  560.                           {
  561.                             if (!Quiet)
  562.                               printf("Scan complete.\n");
  563.                           }
  564.                         }
  565.                           
  566.                         /*-------------------*
  567.                          * End the IFF form. *
  568.                          *-------------------*/
  569.                             
  570.                         PopChunk(IFFHandle);
  571.                         CloseIFF(IFFHandle);
  572.                         Close(IFFHandle->iff_Stream);
  573.                       }
  574.                       else
  575.                         printf("Unable to open file: %s\n", FileName);
  576.                       
  577.                       FreeIFF(IFFHandle);
  578.                     }
  579.                   }
  580.                 }
  581.               }
  582.             }
  583.           }
  584.  
  585.           /*--------------------------------------------*
  586.            * Float the interface READ# signal inactive. *
  587.            *--------------------------------------------*/
  588.         
  589.           ciab.ciapra  |= 0x04;
  590.           ciab.ciaddra &= ~0x04;
  591.  
  592.           FreeMiscResource(MR_PARALLELBITS);    
  593.         }
  594.         else
  595.           printf("Parallel Port resources are currently owned.\n");
  596.       
  597.         FreeMiscResource(MR_PARALLELPORT);
  598.       }
  599.       else
  600.         printf("Parallel Port resources are currently owned.\n");
  601.     }
  602.     
  603.     CloseLibrary(IFFParseBase);
  604.   }
  605.   else
  606.     printf("Unable to open 'iffparse.library' V37).\n");
  607.  
  608.   return;
  609. }
  610.  
  611. /*-------------------------------------------------------------------------------*
  612.  * FUNCTION: ReceiveData                                                         *
  613.  *-------------------------------------------------------------------------------*
  614.  * This function reads data from the scanner.  The interface READ# signal must   *
  615.  * asserted before calling this function, including the sending of a command     *
  616.  * that will actually return data.                                               *
  617.  *-------------------------------------------------------------------------------*
  618.  * INPUTS: Buffer = Buffer to save data.                                         *
  619.  *         Size   = Buffer size.                                                 *
  620.  *                                                                               *
  621.  * OUTPUT: TRUE if successful, or FALSE if aborted by pressing of CTRL_C.        *
  622.  *-------------------------------------------------------------------------------*/
  623.  
  624. BOOL ReceiveData(UBYTE *Buffer, ULONG Size)
  625. {
  626.   ULONG DataCounter, TrialCounter;
  627.   UBYTE Dummy;
  628.   BOOL Success;
  629.   
  630.   Success     = TRUE;
  631.   DataCounter = 0;
  632.         
  633.   do
  634.   {
  635.     TrialCounter = 100;
  636.             
  637.     do
  638.     {
  639.       /*----------------------------------------------------*
  640.        * Wait for the interface BUSY signal to be asserted, *
  641.        * indicating the availability of data.               *
  642.        *----------------------------------------------------*/
  643.       
  644.       if ((ciab.ciapra & 0x01) == 0x01)
  645.       {
  646.         /*----------------------------------------------------*
  647.          * Read the latched data from the scanner.  This will *
  648.          * trigger the generation of a STROBE# pulse.         *
  649.          *----------------------------------------------------*/
  650.         
  651.         Buffer[DataCounter] = ciaa.ciaprb;
  652.         
  653.         /*---------------------------------------------------*
  654.          * A dummy read of the status register provides time *
  655.          * for the CIA chip to generate a STROBE# to clear   *
  656.          * the BUSY driver latch, before the BUSY status is  *
  657.          * polled again.                                     *
  658.          *---------------------------------------------------*/
  659.         
  660.         Dummy = ciab.ciapra;
  661.         DataCounter ++;
  662.       }
  663.  
  664.       TrialCounter --;
  665.     }
  666.     while ((TrialCounter != 0) && (DataCounter != Size));
  667.   
  668.     /*----------------------------*
  669.      * Check for a Break request. *
  670.      *----------------------------*/
  671.   
  672.     if (SetSignal(0,0) & SIGBREAKF_CTRL_C)
  673.     {
  674.       DataCounter = Size;
  675.       Success     = FALSE;
  676.     }
  677.   }
  678.   while (DataCounter != Size);
  679.   
  680.   return Success;
  681. }
  682.